#include "CircularQueue.h"

void enqueue(CircularQueue* queue, EntryType element) {

    /* 队列满不可扩容 */
    queue->data[queue->rear] = malloc(queue->elem_size);
    memcpy(queue->data[queue->rear], element, queue->elem_size);
    queue->rear = (queue->rear + 1) % queue->capacity;
    queue->size++;
}

/* element传入传出参数 */
void dequeue(CircularQueue* queue, EntryType element) {
    if (queue->is_empty(queue)) {
        printf("Queue is empty\n");
        return;
    }
    memcpy(element, queue->data[queue->front], queue->elem_size);
    free(queue->data[queue->front]);
    queue->front = (queue->front + 1) % queue->capacity;
    queue->size--;
}

bool is_empty(CircularQueue* queue) {
    return queue->size == 0;
}

bool is_full(CircularQueue* queue) {
    return queue->size == queue->capacity;
}

void destroy(CircularQueue* queue) {
    for (int i = 0; i < queue->size; i++) {
        free(queue->data[(queue->front + i) % queue->capacity]);
    }
    free(queue->data);
    free(queue);
}

CircularQueue* create_queue(size_t elem_size) {
    CircularQueue* queue = (CircularQueue*)malloc(sizeof(CircularQueue));
    
    queue->data = (DataType)malloc(QUEUE_INITIAL_CAPACITY * sizeof(void*));
    
    queue->front = 0;
    queue->rear = 0;
    queue->size = 0;
    queue->capacity = QUEUE_INITIAL_CAPACITY;
    
    queue->elem_size = elem_size;

    queue->enqueue = enqueue;
    queue->dequeue = dequeue;
    queue->is_empty = is_empty;
    queue->is_full = is_full;
    queue->destroy = destroy;

    return queue;
}